﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Collections;
using System.Text.RegularExpressions;

namespace ThiTracNghiem
{
    public partial class FormQLDSLop : Form
    {
        Stack<Lop> undoStack = new Stack<Lop>();

        public String backupMa = "";
        public String backupTen = "";
        public FormQLDSLop()
        {
            InitializeComponent();
        }

        private void FormQLDSLop_Load(object sender, EventArgs e)
        {
            using (SqlConnection con = new SqlConnection(Program.ConnectionString))
            {
                using (SqlCommand cmd = new SqlCommand("SP_GETALL_LOP", con))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    try
                    {
                        con.Open();
                        SqlDataReader reader = cmd.ExecuteReader();
                        while (reader.Read())
                        {
                            DataGridViewRow row = new DataGridViewRow();
                            row.CreateCells(dgvLop);
                            row.Cells[0].Value = reader[0].ToString().Trim();
                            row.Cells[1].Value = reader[1].ToString().Trim();
                            dgvLop.Rows.Add(row);
                        }
                        reader.Close();
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        
        }

        #region Main buttons event handler: Them, Sua, Xoa, Undo, Timkiem
        private void btnThem_Click(object sender, EventArgs e)
        {
            pnNormal.Visible = true;
            txtMaMH.Text = "";
            txtTenMH.Text = "";
            txtMaMH.ReadOnly = false;
            txtTenMH.ReadOnly = false;

            pnButtonThemHuy.Visible = true;
            btnOK.Text = "Thêm";
            btnThem.Enabled = false;
            btnSua.Enabled = false;
            btnXoa.Enabled = false;
            
            dgvLop.Enabled = false;
        }

        private void btnSua_Click(object sender, EventArgs e)
        {
            if (dgvLop.SelectedRows.Count > 0)
            {
                pnNormal.Visible = true;
                txtMaMH.ReadOnly = false;
                txtTenMH.ReadOnly = false;

                pnButtonThemHuy.Visible = true;
                btnOK.Text = "Xong";
                btnCancel.Text = "Hủy bỏ";

                backupMa = txtMaMH.Text;
                backupTen = txtTenMH.Text;

                btnThem.Enabled = false;
                btnSua.Enabled = false;
                btnXoa.Enabled = false;
                
                dgvLop.Enabled = false;
            }
        }

        private void btnXoa_Click(object sender, EventArgs e)
        {
            if (dgvLop.SelectedRows.Count > 0)
            {
                
                DataGridViewRow row = dgvLop.SelectedRows[0];

                DialogResult result = MessageBox.Show("Bạn chắc chắn muốn xóa lớp này?\nLưu ý: Xóa lớp này đông thời sẽ xóa TẤT CẢ các sinh viên thuộc lớp này.", "Xác nhận", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    Lop mh = new Lop(3, dgvLop.SelectedRows[0].Cells[0].Value.ToString(), dgvLop.SelectedRows[0].Cells[1].Value.ToString());
                    undoStack.Push(mh);
                    btnUndo.Enabled = true;
                    dgvLop.Rows.RemoveAt(dgvLop.SelectedRows[0].Index);
                }
            }
        }
        #endregion

        

        private int isExisting(String MaLop, String TenLop)
        {
            foreach (DataGridViewRow r in dgvLop.Rows)
            {
                if (r.Cells[0].Value.ToString().Trim().ToUpper().Equals(MaLop.ToUpper()))
                {
                    return 1;
                }
                if (r.Cells[1].Value.ToString().Trim().ToUpper().Equals(TenLop.ToUpper()))
                {
                    return 2;
                }
            }
            return 0;
        }

        private int isMaMHExisting(String MaLop)
        {
            foreach (DataGridViewRow r in dgvLop.Rows)
            {
                if (r.Cells[0].Value.ToString().Trim().ToUpper().Equals(MaLop.ToUpper()))
                {
                    return 1;
                }
            }
            return 0;
        }

        private int isTenMHExisting(String TenLop)
        {
            foreach (DataGridViewRow r in dgvLop.Rows)
            {
                if (r.Cells[1].Value.ToString().Trim().ToUpper().Equals(TenLop.ToUpper()))
                {
                    return 1;
                }
            }
            return 0;
        }

        #region Validate Input for textbox MaLop & TenLop
        public static bool ValidateInput(KeyPressEventArgs e)
        {
            bool blDiscardUserInput = true;

            if (Char.IsLetter(e.KeyChar))
                return false;

            // Backspace or Space
            if (e.KeyChar == 8 || e.KeyChar == (char)Keys.Space)
                blDiscardUserInput = false;

            return blDiscardUserInput;
        }

        private void txtMaMH_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = ValidateInput(e);
        }

        private void txtTenMH_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = ValidateInput(e);
        }
        #endregion


        #region OK, Cancel Event Handler - pnButtonThemHuy

        private void btnOK_Click(object sender, EventArgs e)
        {
            txtMaMH.Text = Regex.Replace(txtMaMH.Text, @"\s+", " ");
            txtTenMH.Text = Regex.Replace(txtTenMH.Text, @"\s+", " ");

            String MaLop = txtMaMH.Text.Trim();
            String TenLop = txtTenMH.Text.Trim();

            if (MaLop.Equals("") || TenLop.Equals(""))
            {
                MessageBox.Show("Bạn phải nhập đầy đủ các trường thông tin.", "Cảnh báo", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            if (btnOK.Text.Equals("Thêm"))
            {
                int kq = isExisting(MaLop, TenLop);
                if (kq == 0)
                {
                    DataGridViewRow row = new DataGridViewRow();
                    row.CreateCells(dgvLop);
                    row.Cells[0].Value = MaLop;
                    row.Cells[1].Value = TenLop;
                    dgvLop.Rows.Add(row);

                    Lop mh = new Lop(1, MaLop, TenLop);
                    undoStack.Push(mh);
                    btnUndo.Enabled = true;
                }
                else if (kq == 1)
                {
                    MessageBox.Show("Mã đã tồn tại, xin chọn một mã khác!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }
                else
                {
                    MessageBox.Show("Lớp có tên này đã được nhập!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                    return;
                }

                pnButtonThemHuy.Visible = false;
                dgvLop.Rows[dgvLop.RowCount - 1].Selected = true;
                txtMaMH.ReadOnly = true;
                txtTenMH.ReadOnly = true;
                btnThem.Enabled = true;
                btnXoa.Enabled = true;
                
                btnSua.Enabled = true;
                dgvLop.Enabled = true;
            }
            else
            {

                if (MaLop.Equals(backupMa) && TenLop.Equals(backupTen))
                {
                    pnButtonThemHuy.Visible = false;
                    txtMaMH.ReadOnly = true;
                    txtTenMH.ReadOnly = true;
                    btnThem.Enabled = true;
                    btnXoa.Enabled = true;
                    btnSua.Enabled = true;
                    dgvLop.Enabled = true;
                    return;
                }
                Lop mh = new Lop(2, MaLop, TenLop);

                if (!MaLop.Equals(backupMa))
                {
                    int kq = isMaMHExisting(MaLop);

                    if (kq == 1)
                    {
                        MessageBox.Show("Mã đã tồn tại, xin chọn một mã khác!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                }

                if (!TenLop.ToUpper().Equals(backupTen.ToUpper()))
                {
                    int kq = isTenMHExisting(TenLop);
                    if (kq == 1)
                    {
                        MessageBox.Show("Lớp có tên này đã được nhập!", "Lỗi", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return;
                    }
                }

                mh.MaLopOld = backupMa;
                mh.TenLopOld = backupTen;

                undoStack.Push(mh);
                btnUndo.Enabled = true;

                DataGridViewRow row = dgvLop.SelectedRows[0];
                row.Cells[0].Value = MaLop;
                row.Cells[1].Value = TenLop;
                pnButtonThemHuy.Visible = false;
                txtMaMH.ReadOnly = true;
                txtTenMH.ReadOnly = true;
                btnThem.Enabled = true;
                btnXoa.Enabled = true;
                
                btnSua.Enabled = true;
                dgvLop.Enabled = true;
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            pnButtonThemHuy.Visible = false;
            dgvLop.Enabled = true;

            if (dgvLop.SelectedRows.Count > 0)
            {
                DataGridViewRow row = dgvLop.SelectedRows[0];
                txtMaMH.Text = row.Cells[0].Value.ToString();
                txtTenMH.Text = row.Cells[1].Value.ToString();
            }

            txtMaMH.ReadOnly = true;
            txtTenMH.ReadOnly = true;
            btnThem.Enabled = true;
            btnXoa.Enabled = true;
            
            btnSua.Enabled = true;
        }
        #endregion

        private void btnUndo_Click(object sender, EventArgs e)
        {
            if (undoStack.Count > 0)
            {
                Lop mh = undoStack.Peek();
                switch (mh.MaLenh)
                {
                    case 1:
                        foreach (DataGridViewRow r in dgvLop.Rows)
                        {
                            if (r.Cells[0].Value.ToString().Trim().Equals(mh.MaLop))
                            {
                                int index = r.Index;
                                if (index - 1 >= 0)
                                {
                                    dgvLop.Rows[index - 1].Selected = true;
                                }

                                dgvLop.Rows.RemoveAt(index);
                                undoStack.Pop();
                                if (undoStack.Count == 0)
                                    btnUndo.Enabled = false;
                                break;
                            }
                        }
                        break;
                    case 2:
                        foreach (DataGridViewRow r in dgvLop.Rows)
                        {
                            if (r.Cells[0].Value.ToString().Trim().Equals(mh.MaLop))
                            {
                                int index = r.Index;
                                r.Selected = true;

                                r.Cells[0].Value = mh.MaLopOld;
                                r.Cells[1].Value = mh.TenLopOld;
                                undoStack.Pop();
                                if (undoStack.Count == 0)
                                    btnUndo.Enabled = false;
                                break;
                            }
                        }
                        break;
                    case 3:
                        DataGridViewRow row = new DataGridViewRow();
                        row.CreateCells(dgvLop);
                        row.Cells[0].Value = mh.MaLop;
                        row.Cells[1].Value = mh.TenLop;
                        dgvLop.Rows.Add(row);

                        undoStack.Pop();
                        if (undoStack.Count == 0)
                            btnUndo.Enabled = false;
                        break;
                }
            }
        }

        private void dgvMonHoc_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvLop.SelectedRows.Count > 0)
            {
                DataGridViewRow row = dgvLop.SelectedRows[0];
                txtMaMH.Text = row.Cells[0].Value.ToString();
                txtTenMH.Text = row.Cells[1].Value.ToString();
            }
            else
            {
                txtMaMH.Text = "";
                txtTenMH.Text = "";
            }
        }

        private void btnHuyAll_Click(object sender, EventArgs e)
        {
            this.Dispose();
        }

        private void btnGhiAll_Click(object sender, EventArgs e)
        {
            using (SqlConnection con = new SqlConnection(Program.ConnectionString))
            {
                SqlCommand cmd = new SqlCommand();
                cmd.Connection = con;
                cmd.CommandType = CommandType.StoredProcedure;
                con.Open();
                for (int i = undoStack.Count - 1; i >= 0; i--)
                {
                    Lop obj = undoStack.ElementAt(i);
                    cmd.Parameters.Clear();
                    try
                    {
                        switch (obj.MaLenh)
                        {
                            case 1:
                                cmd.CommandText = "SP_INS_LOP";
                                cmd.Parameters.Add("@MALOP", SqlDbType.Char).Value = obj.MaLop;
                                cmd.Parameters.Add("@TENLOP", SqlDbType.NVarChar).Value = obj.TenLop;
                                cmd.ExecuteNonQuery();
                                break;

                            case 2:
                                cmd.CommandText = "SP_UPDATE_LOP";
                                cmd.Parameters.Add("@MACU", SqlDbType.Char).Value = obj.MaLopOld;
                                cmd.Parameters.Add("@MALOP", SqlDbType.Char).Value = obj.MaLop;
                                cmd.Parameters.Add("@TENLOP", SqlDbType.NVarChar).Value = obj.TenLop;
                                cmd.ExecuteNonQuery();
                                break;
                            case 3:
                                cmd.CommandText = "SP_DEL_LOP";
                                cmd.Parameters.Add("@MaLop", SqlDbType.Char).Value = obj.MaLop;
                                cmd.ExecuteNonQuery();
                                break;
                        }
                    }
                    catch (System.Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
                undoStack.Clear();
                btnUndo.Enabled = false;
                MessageBox.Show("Ghi xuống cơ sở dữ liệu thành công!", "Xin chúc mừng", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }

        private void txtMaMH_KeyPress_1(object sender, KeyPressEventArgs e)
        {
            e.Handled = ValidateInputMa(e);
        }

        public static bool ValidateInputMa(KeyPressEventArgs e)
        {
            bool blDiscardUserInput = true;

            if (Char.IsLetter(e.KeyChar))
                return false;

            if (Char.IsNumber(e.KeyChar))
                return false;

            // Backspace or Space
            if (e.KeyChar == 8)
                blDiscardUserInput = false;

            return blDiscardUserInput;
        }
    }
}
